/**
 * Vue 文件解析器
 * 负责解析 .vue 文件的 template、script、style 部分
 */
class VueFileParser {
  constructor() {
    // 定义各部分的正则表达式
    this.templateRegex = /<template[^>]*>([\s\S]*?)<\/template>/i;
    this.scriptRegex = /<script[^>]*>([\s\S]*?)<\/script>/i;
    this.styleRegex = /<style[^>]*>([\s\S]*?)<\/style>/i;
  }

  /**
   * 解析 Vue 文件内容
   * @param {string} content - 文件内容
   * @param {Object} options - 解析选项
   * @returns {Promise<Object>} 解析结果
   */
  async parse(content, options = {}) {
    try {
      // 解析各个部分
      const templateMatch = content.match(this.templateRegex);
      const scriptMatch = content.match(this.scriptRegex);
      const styleMatch = content.match(this.styleRegex);

      // 计算各部分的行数
      const templateContent = templateMatch ? templateMatch[1] : '';
      const scriptContent = scriptMatch ? scriptMatch[1] : '';
      const styleContent = styleMatch ? styleMatch[1] : '';

      const templateLines = this.countLines(templateContent);
      const scriptLines = this.countLines(scriptContent);
      const styleLines = this.countLines(styleContent);

      // 检测语言特性
      const language = this.detectLanguage(content, scriptContent, styleContent);

      // 分析组件结构
      const structure = this.analyzeStructure(content, options);

      const totalLines = templateLines + scriptLines + styleLines;

      return {
        templateLines,
        scriptLines,
        styleLines,
        totalLines,
        language,
        structure,
        hasTemplate: !!templateMatch,
        hasScript: !!scriptMatch,
        hasStyle: !!styleMatch,
        // 完整性检查
        completeness: this.assessCompleteness(templateMatch, scriptMatch, styleMatch)
      };
    } catch (error) {
      throw new Error(`解析 Vue 文件失败: ${error.message}`);
    }
  }

  /**
   * 计算有效行数（排除空行和纯注释行）
   * @param {string} content - 内容
   * @returns {number} 有效行数
   */
  countLines(content) {
    if (!content) return 0;

    const lines = content.split('\n');
    let count = 0;

    for (const line of lines) {
      const trimmedLine = line.trim();

      // 跳过空行
      if (trimmedLine === '') continue;

      // 跳过纯注释行（但保留代码中的注释）
      if (this.isPureComment(trimmedLine)) continue;

      count++;
    }

    return count;
  }

  /**
   * 判断是否为纯注释行
   * @param {string} line - 行内容
   * @returns {boolean} 是否为纯注释
   */
  isPureComment(line) {
    // HTML 注释
    if (line.startsWith('<!--') && line.endsWith('-->')) return true;

    // JavaScript 注释
    if (line.startsWith('//') || line.startsWith('/*')) return true;

    // CSS 注释
    if (line.startsWith('/*') || line.startsWith('*')) return true;

    return false;
  }

  /**
   * 检测语言特性
   * @param {string} fullContent - 完整内容
   * @param {string} scriptContent - 脚本内容
   * @param {string} styleContent - 样式内容
   * @returns {Object} 语言信息
   */
  detectLanguage(fullContent, scriptContent, styleContent) {
    return {
      // 检测 JavaScript/TypeScript
      isTypeScript: scriptContent.includes('lang="ts"') ||
                   scriptContent.includes('lang=\'ts\'') ||
                   scriptContent.includes(':') && scriptContent.includes('as '),

      // 检测样式预处理器
      stylePreprocessor: this.detectStylePreprocessor(fullContent),

      // 检测模板语法特性
      templateFeatures: this.detectTemplateFeatures(fullContent)
    };
  }

  /**
   * 检测样式预处理器
   * @param {string} content - 内容
   * @returns {string} 预处理器类型
   */
  detectStylePreprocessor(content) {
    if (content.includes('lang="scss"') || content.includes('lang=\'scss\'')) return 'scss';
    if (content.includes('lang="sass"') || content.includes('lang=\'sass\'')) return 'sass';
    if (content.includes('lang="less"') || content.includes('lang=\'less\'')) return 'less';
    if (content.includes('lang="stylus"') || content.includes('lang=\'stylus\'')) return 'stylus';
    return 'css';
  }

  /**
   * 检测模板语法特性
   * @param {string} content - 内容
   * @returns {Object} 模板特性
   */
  detectTemplateFeatures(content) {
    return {
      hasVIf: content.includes('v-if'),
      hasVFor: content.includes('v-for'),
      hasVModel: content.includes('v-model'),
      hasSlot: content.includes('<slot'),
      hasComponent: content.includes('<component') || content.includes('is='),
      hasJSX: content.includes('render(') || content.includes('jsx'),
      hasComposition: content.includes('setup>') || content.includes('lang="ts"')
    };
  }

  /**
   * 分析组件结构
   * @param {string} content - 内容
   * @param {Object} options - 选项
   * @returns {Object} 组件结构信息
   */
  analyzeStructure(content, options = {}) {
    if (!options.detailed) {
      return { basic: true };
    }

    return {
      componentCount: (content.match(/<[^\/\s>][^>]*>/g) || []).length,
      propCount: (content.match(/props\s*:\s*{[^}]*}/g) || []).length,
      computedCount: (content.match(/computed\s*:\s*{[^}]*}/g) || []).length,
      methodCount: (content.match(/methods\s*:\s*{[^}]*}/g) || []).length,
      watchCount: (content.match(/watch\s*:\s*{[^}]*}/g) || []).length
    };
  }

  /**
   * 评估文件完整性
   * @param {Object} templateMatch - 模板匹配结果
   * @param {Object} scriptMatch - 脚本匹配结果
   * @param {Object} styleMatch - 样式匹配结果
   * @returns {Object} 完整性信息
   */
  assessCompleteness(templateMatch, scriptMatch, styleMatch) {
    const hasAll = !!(templateMatch && scriptMatch && styleMatch);
    const hasMain = !!(templateMatch || scriptMatch);

    let score = 0;
    if (templateMatch) score += 33;
    if (scriptMatch) score += 34;
    if (styleMatch) score += 33;

    return {
      score,
      hasAll,
      hasMain,
      missing: {
        template: !templateMatch,
        script: !scriptMatch,
        style: !styleMatch
      }
    };
  }
}

module.exports = VueFileParser;